use std::io::Read;
use std::path::Path;

use indicatif::{ProgressBar, ProgressStyle};
use tar::Archive;
use xz::read::XzDecoder;

use crate::runtime::runtime::error::InternalError;
use crate::runtime::runtime::result::InternalErrorResult;
use crate::util::util::reader::proxy::Proxy;

pub fn decompress<R: Read, P: AsRef<Path>>(rp: P, r: R, s: u64, t: P) -> InternalErrorResult<()> {
    println!("解压文件: {} -> {}", rp.as_ref().to_str().unwrap(), t.as_ref().to_str().unwrap());

    // 进度条
    let pb = ProgressBar::new(s);
    pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes}").unwrap().progress_chars("=>-"));

    let decoder = XzDecoder::new(r);

    // reader proxy
    let proxy = Proxy::new(decoder, |us| pb.inc(us as u64));

    // tar decoder
    let mut archive = Archive::new(proxy);

    archive.unpack(t).map_err(|e| InternalError::new(format!("Could not decompress tar.xz file: {}", e.to_string())))?;
    pb.finish();

    Ok(())
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_decompress_tar_xz() {
        // TODO
    }
}